package dao

import (
	"context"
	"go-shop-admin/internal/model"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

type AuthDao struct {
	*gorm.DB
}

// 指定查询的字段
var authSelectField = []string{"id", "account", "username", "password", "desc", "phone", "email", "avatar", "role_id", "login_num", "status", "sort", "created_at"}

// NewAuthDao 把init init_mysql的Db复制过来
func NewAuthDao(ctx context.Context) *AuthDao {
	return &AuthDao{NewDBClient(ctx)}
}

// NewAuthDaoByDB  方法二 把init中的db拿过来  ，当一个函数里，有多个dao ,既有AuthDao，又有GoodsDao ,可用这个方法实现对db的复用,都使用一个db，减少对数据库的链接
func NewAuthDaoByDB(db *gorm.DB) *AuthDao {
	return &AuthDao{db}
}

// GetList 获取列表
func (d *AuthDao) GetList(whereMap WhereStruct) (total int64, object []*model.Auth, err error) {
	d.DB.Model(&model.Auth{}).Where(whereMap.Where).Not(whereMap.NotWhere).Or(whereMap.OrWhere).Count(&total)
	err = d.DB.Model(&model.Auth{}).Select(authSelectField).Where(whereMap.Where).Not(whereMap.NotWhere).Or(whereMap.OrWhere).Order(orderCondition).Find(&object).Error //find() 找全部符合条件的
	return
}

// GetById 通过id获取用户信息
func (d *AuthDao) GetById(id uint) (object *model.Auth, err error) {
	err = d.DB.Model(&model.Auth{}).Select(authSelectField).Where("id=?", id).First(&object).Error
	return
}

// ExistOrNotByWhere 通过 账号/用户名/手机号/邮箱 判断用户是否存在
func (d *AuthDao) ExistOrNotByWhere(whereMap WhereStruct) (auth *model.Auth, exist bool, err error) {
	var count int64
	err = d.DB.Model(&model.Auth{}).Where(whereMap.Where).Not(whereMap.NotWhere).Or(whereMap.OrWhere).Count(&count).Error
	if count == 0 {
		return auth, false, err
	}
	err = d.DB.Model(&model.Auth{}).Select(authSelectField).Where(whereMap.Where).Not(whereMap.NotWhere).Or(whereMap.OrWhere).First(&auth).Error
	//如果user == 空
	//if user == nil || err == gorm.ErrRecordNotFound {
	//	return nil, false, err
	//}
	if err != nil {
		return auth, false, err
	}
	return auth, true, nil
}

// AuthCreate 新增
func (d *AuthDao) AuthCreate(auth *model.Auth) error {
	err := d.DB.Model(&model.Auth{}).Create(&auth).Error
	return err
}

// AuthUpdate 更改
func (d *AuthDao) AuthUpdate(id uint, auth *model.Auth) error {
	return d.DB.Model(&model.Auth{}).Where("id=?", id).Updates(&auth).Error
}

// Delete 删除
func (d *AuthDao) Delete(ids []string) error {
	return d.DB.Delete(&model.Auth{}, ids).Error
}

/*
		CheckPassword 检验密码
		encryptPwd string  已经加密的字符
	    password string 还未加密的字符
*/
func CheckPassword(encryptPwd, password string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(encryptPwd), []byte(password))
	return err == nil
	//如果err == nil 返回 true，反之
}
